﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
using Jink.Protocol.Core;
using Jink.Protocol.Core.Headers;
using XenoGears.Collections;
using XenoGears.Collections.Virtual;
using XenoGears.Reflection.Simple;
using System.Linq;

namespace Jink.Protocol.Media.Http
{
    public class HttpResponseMedia : IResponseMedia
    {
        private readonly HttpResponse _response;
        private readonly HttpContext _context;

        public HttpResponseMedia(HttpResponse response)
        {
            _response = response;
            _context = (HttpContext)_response.Get("_context");
        }

        public static implicit operator HttpResponseMedia(HttpResponse response)
        {
            return new HttpResponseMedia(response);
        }

        public int StatusCode { get { return _response.StatusCode; } set { _response.StatusCode = value; } }

        public Encoding HeaderEncoding { get { return _response.HeaderEncoding; } set { _response.HeaderEncoding = value; } }

        public IDictionary<ResponseHeader, String> Headers
        {
            get
            {
                return new VirtualDictionary<ResponseHeader, String>(
                    () => _response.Headers.Cast<String>().ToDictionary(name => name.ToResponseHeader(), name => _response.Headers[name]),
                    (header, value) => _response.Headers.Add(header.ToHttpHeader(), value),
                    (header, value) => _response.Headers[header.ToHttpHeader()] = value,
                    header => _response.Headers.Remove(header.ToHttpHeader())
                );
            }
        }

        public IDictionary<String, String> Cookies
        {
            get 
            { 
                return new VirtualDictionary<String, String>(
                    () => _response.Cookies.Cast<HttpCookie>().ToDictionary(coo => coo.Name, coo => coo.Value),
                    (name, value) => _response.Cookies.Add(new HttpCookie(name, value)),
                    (name, value) => _response.Cookies[name].Value = value,
                    name => _response.Cookies.Remove(name)
                );
            }
        }

        public Encoding ContentEncoding { get { return _response.ContentEncoding; } set { _response.ContentEncoding = value; } }
        public String ContentType { get { return _response.ContentType; } set { _response.ContentType = value; } }
        public TextWriter Content { get { return _response.Output; } }
        public Stream ContentStream { get { return _response.OutputStream; } }

        public void DoComplete()
        {
            _response.End();
        }
    }
}
